// ============================================================================
//
// Copyright (C) 2006-2008 Dengues
//
// Google Group: http://groups.google.com/group/dengues
//
// QQ Group: 24885404
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// ============================================================================
package org.dengues.reports.editor.design.ruler;

import java.util.ArrayList;
import java.util.List;

import org.dengues.reports.editor.design.models.AbstractReportsElement;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.rulers.RulerProvider;

/**
 * Qiang.Zhang.Adolf@gmail.com class global comment. Detailled comment <br/>
 * 
 * $Id: Dengues.epf Qiang.Zhang.Adolf@gmail.com 2008-7-31 qiang.zhang $
 * 
 */
public class RepEditorRuler extends AbstractReportsElement {

    private Rectangle leftSpace = new Rectangle();

    public static final String PROPERTY_UNIT = "units changed"; //$NON-NLS-1$

    public static final String PROPERTY_CHILDREN = "children changed"; //$NON-NLS-1$

    private static final long serialVersionUID = 13423423499990L;

    private boolean horizontal;

    private List<RepEditorGuide> guides = new ArrayList<RepEditorGuide>();

    private int unit;

    private boolean marginOff = false;

    private RepEditorGuide left, right;

    /**
     * Returns the left margin.
     * 
     * @return Returns the leftMargin.
     */
    public int getLeftMargin() {
        if (left != null) {
            return left.getPosition();
        }
        return -1;
    }

    /**
     * Sets the left magin of the ruler.
     * 
     * @param leftMargin The leftMargin to set.
     */
    public void setLeftMargin(int newMargin) {
        if (!marginOff) {
            if (left == null) {
                left = new RepEditorGuide(!isHorizontal(), RepEditorGuide.LEFT);
                left.setPosition(newMargin);
                addGuide(left);
            } else {
                left.setPosition(newMargin);
            }
        }
    }

    /**
     * @param rightMargin The rightMargin to set.
     */
    public void setRightMargin(int newMargin) {
        if (!marginOff) {
            if (right == null) {
                right = new RepEditorGuide(!isHorizontal(), RepEditorGuide.RIGHT);
                right.setPosition(newMargin);
                addGuide(right);
            } else {
                right.setPosition(newMargin);
            }
        }
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com Comment method "getRightMargin".
     * 
     * @return
     */
    public int getRightMargin() {
        if (right != null) {
            return right.getPosition();
        }
        return -1;
    }

    /**
     * Getter for marginOff.
     * 
     * @return the marginOff
     */
    public boolean isMarginOff() {
        return this.marginOff;
    }

    /**
     * Sets the marginOff.
     * 
     * @param marginOff the marginOff to set
     */
    public void setMarginOff(boolean marginOff) {
        this.marginOff = marginOff;
        if (marginOff) {
            removeGuide(left);
            removeGuide(right);
            left = null;
            right = null;
        }
    }

    /**
     * Getter for leftSpace.
     * 
     * @return the leftSpace
     */
    public Rectangle getLeftSpace() {
        return this.leftSpace;
    }

    /**
     * Sets the leftSpace.
     * 
     * @param leftSpace the leftSpace to set
     */
    public void setLeftSpace(Rectangle space) {
        if (!leftSpace.equals(space)) {
            Rectangle oldSpace = leftSpace;
            leftSpace = space;
            firePropertyChange(PROPERTY_UNIT, oldSpace, space);
        }
    }

    public RepEditorRuler(boolean isHorizontal) {
        this(isHorizontal, RulerProvider.UNIT_INCHES);
    }

    /**
     * private List<RepEditorGuide> guides = new ArrayList<RepEditorGuide>();
     * 
     * /** Getter for guides.
     * 
     * @return the guides
     */
    public List<RepEditorGuide> getGuides() {
        return this.guides;
    }

    /**
     * Adds ruler guide.
     * 
     * @param guide
     */
    public void addGuide(RepEditorGuide guide) {
        if (!guides.contains(guide)) {
            guide.setHorizontal(!isHorizontal());
            guides.add(guide);
            fireStructureChange(PROPERTY_CHILDREN, guide);
        }
    }

    /**
     * Removes the guide from the ruler.
     * 
     * @param guide
     */
    public void removeGuide(RepEditorGuide guide) {
        if (guides.remove(guide)) {
            fireStructureChange(PROPERTY_CHILDREN, guide);
        }
    }

    /**
     * Qiang.Zhang.Adolf@gmail.com SubjectRuler constructor comment.
     * 
     * @param b
     */
    public RepEditorRuler(boolean isHorizontal, int unit) {
        horizontal = isHorizontal;
        setUnit(unit);
    }

    /**
     * Getter for horizontal.
     * 
     * @return the horizontal
     */
    public boolean isHorizontal() {
        return this.horizontal;
    }

    /**
     * Sets the horizontal.
     * 
     * @param horizontal the horizontal to set
     */
    public void setHorizontal(boolean horizontal) {
        this.horizontal = horizontal;
    }

    /**
     * Getter for unit.
     * 
     * @return the unit
     */
    public int getUnit() {
        return this.unit;
    }

    /**
     * Sets the unit.
     * 
     * @param newUnit the unit to set
     */
    public void setUnit(int newUnit) {
        if (unit != newUnit) {
            int oldUnit = unit;
            unit = newUnit;
            firePropertyChange(PROPERTY_UNIT, oldUnit, newUnit);
        }
    }
}
